package com.quectel.cms.config.websocket;

import com.quectel.business.common.websocket.send.SendMsgType;
import com.quectel.cms.config.websocket.msg.req.ReqMsg;
import com.quectel.cms.config.websocket.msg.req.ReqMsgType;
import com.quectel.cms.constants.CmsRedisCacheConstants;
import com.quectel.util.common.JacksonUtils;
import com.quectel.util.redis.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import java.util.Map;

/**
 * websocket配置
 *
 * @author: caolu
 * @email: louis.cao@quectel.com
 * @date: 2023-05-18 15:46:00
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new WebSocketHandler(), "/ws").setAllowedOrigins("*");
    }

    /**
     * 实现类
     */
    @Slf4j
    private static class WebSocketHandler extends AbstractWebSocketHandler {
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            log.debug("afterConnectionEstablished");
        }

        @Override
        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
            ReqMsg reqMsg = JacksonUtils.parse(message.getPayload(), ReqMsg.class);
            if (ReqMsgType.REGISTER.getMsgTypeFlag().equals(reqMsg.getMsgType())) {
                // 注册消息
                Map<String, Object> params = reqMsg.getParams();
                Object villageId = params.get("villageId");
                Object token = params.get("token");
                if (villageId == null || token == null) {
                    session.close();
                    return;
                }

                String loginUserInfoStr = RedisUtils.get(CmsRedisCacheConstants.TOKEN_USER_PREFIX + token);
                if (StringUtils.isBlank(loginUserInfoStr)) {
                    // 权限不合法 更深层次的这里没有校验
                    session.close();
                    return;
                }
                SocketSessionUtils.registerSession(Long.valueOf(String.valueOf(villageId)), String.valueOf(token), session);
                SocketSessionUtils.sendMsg(Long.valueOf(String.valueOf(villageId)), String.valueOf(token), SendMsgType.REGISTER_SUCCESS.getMsgTypeFlag(),null,null, null);
            } else if (ReqMsgType.PING.getMsgTypeFlag().equals(reqMsg.getMsgType())) {
                Map<String, Object> params = reqMsg.getParams();
                Object villageId = params.get("villageId");
                Object token = params.get("token");
                SocketSessionUtils.sendMsg(Long.valueOf(String.valueOf(villageId)), String.valueOf(token), SendMsgType.PONG.getMsgTypeFlag(), null, null, null);
            }

        }

        @Override
        public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
            SocketSessionUtils.closeSession(session);
        }

        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            SocketSessionUtils.closeSession(session);
        }
    }
}
